package szf.im.server.boot;

import io.netty.bootstrap.Bootstrap;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.protobuf.ProtobufDecoder;
import io.netty.handler.codec.protobuf.ProtobufEncoder;
import io.netty.handler.codec.protobuf.ProtobufVarint32FrameDecoder;
import io.netty.handler.codec.protobuf.ProtobufVarint32LengthFieldPrepender;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import szf.im.server.data.MessageOuterClass;
import szf.im.server.hander.MyServerChannelHandler;
import szf.im.server.hander.ProtoBufMsgHandler;
import szf.im.server.util.*;

import javax.annotation.PostConstruct;

/**
 * @author shizhanfu
 */
@Component
public class ImServer {

    @Autowired
    private Config cfg;
    @Autowired
    private ZkCfg zkCfg;

    @PostConstruct
    public void start() throws Exception {
        System.out.println("im server start begin");
        System.out.println("cfg:" + cfg.getPort());
        ServerBootstrap bootstrap = new ServerBootstrap();
        EventLoopGroup parent = new NioEventLoopGroup();
        EventLoopGroup worker = new NioEventLoopGroup();
        bootstrap.group(parent, worker).channel(NioServerSocketChannel.class)
                .childHandler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    protected void initChannel(SocketChannel sc) throws Exception {
//                        sc.pipeline().addLast(new StringDecoder());
//                        sc.pipeline().addLast(new StringEncoder());
//                        sc.pipeline().addLast(new MyServerChannelHandler());
                        //解码器，通过Google Protocol Buffers序列化框架动态的切割接收到的ByteBuf
                        sc.pipeline().addLast(new ProtobufVarint32FrameDecoder());
                        //服务器端接收的是客户端RequestUser对象，所以这边将接收对象进行解码生产实列
                        sc.pipeline().addLast(new ProtobufDecoder(MessageOuterClass.Message.getDefaultInstance()));
                        //Google Protocol Buffers编码器
                        sc.pipeline().addLast(new ProtobufVarint32LengthFieldPrepender());
                        //Google Protocol Buffers编码器
                        sc.pipeline().addLast(new ProtobufEncoder());
                        sc.pipeline().addLast(new ProtoBufMsgHandler());
                    }
                });
        bootstrap.option(ChannelOption.SO_BACKLOG, 2048);
        //socket channel的设置,维持链接的活跃，清除死链接
        bootstrap.childOption(ChannelOption.SO_KEEPALIVE, true);
        bootstrap.childOption(ChannelOption.TCP_NODELAY, true);
        bootstrap.bind(cfg.getPort());
        //.channel().closeFuture().sync();
        System.out.println("im start success");
        ZkClient.getInstance(zkCfg.getConn());
        ZkClient.CreateNode(Const.Netty_Server, NetUtil.getIp(cfg.getPort()));
    }
}
